package com.df.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class TimeAnalyzer {
    
    private final Map<String, TaskTimeline> taskTimelines = new ConcurrentHashMap<>();
    
    public void recordTaskStart(String processInstanceId, String taskId, String taskName) {
        TaskTimeline timeline = taskTimelines.computeIfAbsent(processInstanceId, k -> new TaskTimeline());
        timeline.recordTaskStart(taskId, taskName);
        
        log.info("=== 任务时间分析 ===");
        log.info("流程实例: {}", processInstanceId);
        log.info("任务开始: {} ({})", taskName, taskId);
        log.info("开始时间: {}", System.currentTimeMillis());
        
        if (timeline.getTaskCount() > 1) {
            long timeSinceLastTask = timeline.getTimeSinceLastTask();
            log.info("距离上一个任务: {}ms", timeSinceLastTask);
        }
        
        log.info("==================");
    }
    
    public void recordTaskComplete(String processInstanceId, String taskId, String taskName, long processingTime) {
        TaskTimeline timeline = taskTimelines.get(processInstanceId);
        if (timeline != null) {
            timeline.recordTaskComplete(taskId, processingTime);
            
            log.info("=== 任务完成分析 ===");
            log.info("流程实例: {}", processInstanceId);
            log.info("任务完成: {} ({})", taskName, taskId);
            log.info("处理时间: {}ms", processingTime);
            log.info("总耗时: {}ms", timeline.getTotalTime());
            log.info("==================");
        }
    }
    
    public void analyzeProcessTimeline(String processInstanceId) {
        TaskTimeline timeline = taskTimelines.get(processInstanceId);
        if (timeline != null) {
            log.info("=== 流程时间线分析 ===");
            log.info("流程实例: {}", processInstanceId);
            log.info("总任务数: {}", timeline.getTaskCount());
            log.info("总耗时: {}ms", timeline.getTotalTime());
            log.info("平均任务间隔: {}ms", timeline.getAverageTaskInterval());
            log.info("=====================");
        }
    }
    
    private static class TaskTimeline {
        private final Map<String, TaskInfo> tasks = new HashMap<>();
        private long firstTaskStartTime = 0;
        private long lastTaskCompleteTime = 0;
        
        public void recordTaskStart(String taskId, String taskName) {
            long currentTime = System.currentTimeMillis();
            if (firstTaskStartTime == 0) {
                firstTaskStartTime = currentTime;
            }
            
            tasks.put(taskId, new TaskInfo(taskName, currentTime));
        }
        
        public void recordTaskComplete(String taskId, long processingTime) {
            TaskInfo taskInfo = tasks.get(taskId);
            if (taskInfo != null) {
                taskInfo.setCompleteTime(System.currentTimeMillis());
                taskInfo.setProcessingTime(processingTime);
                lastTaskCompleteTime = taskInfo.getCompleteTime();
            }
        }
        
        public int getTaskCount() {
            return tasks.size();
        }
        
        public long getTimeSinceLastTask() {
            if (lastTaskCompleteTime == 0) {
                return 0;
            }
            return System.currentTimeMillis() - lastTaskCompleteTime;
        }
        
        public long getTotalTime() {
            if (firstTaskStartTime == 0 || lastTaskCompleteTime == 0) {
                return 0;
            }
            return lastTaskCompleteTime - firstTaskStartTime;
        }
        
        public double getAverageTaskInterval() {
            if (getTaskCount() <= 1) {
                return 0;
            }
            return (double) getTotalTime() / (getTaskCount() - 1);
        }
    }
    
    private static class TaskInfo {
        private final String taskName;
        private final long startTime;
        private long completeTime;
        private long processingTime;
        
        public TaskInfo(String taskName, long startTime) {
            this.taskName = taskName;
            this.startTime = startTime;
        }
        
        public void setCompleteTime(long completeTime) {
            this.completeTime = completeTime;
        }
        
        public void setProcessingTime(long processingTime) {
            this.processingTime = processingTime;
        }
        
        public long getCompleteTime() {
            return completeTime;
        }
        
        public long getProcessingTime() {
            return processingTime;
        }
    }
} 